var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __read = (this && this.__read) || function (o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
};
var __spread = (this && this.__spread) || function () {
    for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
    return ar;
};
import React, { useEffect, useState, useRef } from "react";
import { PickerView, PickerViewColumn, View } from "@tarojs/components";
/**
 * DatePicker 选择时间Picker
 */
var DatePicker = function (_a) {
    var _b = _a.mode, mode = _b === void 0 ? "date" : _b, _c = _a.minDate, minDate = _c === void 0 ? new Date("1900/01/01") : _c, _d = _a.maxDate, maxDate = _d === void 0 ? new Date("2100/12/31") : _d, _e = _a.defaultValue, defaultValue = _e === void 0 ? new Date() : _e, onChange = _a.onChange, columnStyle = _a.columnStyle, textStyle = _a.textStyle, activeTextStyle = _a.activeTextStyle, style = _a.style;
    // 设置picker默认植
    var _f = __read(useState([]), 2), pickerValue = _f[0], setPickerValue = _f[1];
    // 1 2 3列数据
    var _g = __read(useState([]), 2), pickerData = _g[0], setPickerData = _g[1];
    var currentIndexsRef = useRef();
    useEffect(function () {
        if (!(minDate <= defaultValue && defaultValue <= maxDate)) {
            return console.error('默认时间不在范围内');
        }
    }, [minDate, maxDate, defaultValue]);
    // 计算出数据源
    useEffect(function () {
        var pickerData = []; // 源数据
        // 1. 年 最小、最大
        var years = [];
        for (var year = minDate.getFullYear(); year <= maxDate.getFullYear(); year++) {
            years.push(year + "年");
        }
        pickerData.push(years);
        if (mode === "date" || mode === "date-year-month") {
            // 2. 月
            var months = [];
            for (var i = 1; i <= 12; i++) {
                months.push(i + '月');
            }
            pickerData.push(months);
        }
        if (mode === "date") {
            // 3. 日
            var days = [];
            days = getDayRange(defaultValue.getFullYear(), defaultValue.getMonth() +
                1);
            pickerData.push(days);
        }
        var validDate = new Date(defaultValue.getFullYear() + "/" + (defaultValue.getMonth() +
            1) + "/" + defaultValue.getDate());
        // 计算数据源、日期所对应的下标索引
        var pickerValue = getPickerValue(pickerData, validDate);
        currentIndexsRef.current = pickerValue;
        setPickerData(pickerData);
        setPickerValue(pickerValue);
        // 主动回调onChange
        onChange && onChange(validDate);
    }, []);
    /**
     * @param 是否闰年 fullYear: 年
     * @returns 返回 bool
     * */
    function isRunYear(fullYear) {
        return fullYear % 4 == 0 && (fullYear % 100 != 0 || fullYear % 400 == 0);
    }
    /**
     * @param 输入年月 y: 年  m: 月
     * @returns 返回 日期范围  string[]  1-28号  1-29号  1-30号  1-31号
     * */
    var getDayRange = function (y, m) {
        var numberOfDays = [1, 3, 5, 7, 8, 10, 12].includes(m) ? 31 : 30;
        if (Number(m) === 2) {
            if (y && isRunYear(y)) {
                numberOfDays = 29;
            }
            else {
                numberOfDays = 28;
            }
        }
        var days = [];
        for (var i = 1; i <= numberOfDays; i++) {
            days.push(i + '日');
        }
        return days;
    };
    /**
     *  根据年月日数据源、下标索引，计算出对组合后的日期
     *  @param data string[][]  年月日数据源
     *  @param indexs number[]  下标索引数组
     *  @returns number[]  返回拼接的字符串 eg: [2000,05,11]
     */
    var getChangeDate = function (data, indexs) {
        var date = [];
        for (var index = 0; index < data.length; index++) {
            var elements = data[index]; // 列数组
            var row = indexs[index]; // 列对应的行索引
            if (elements && elements[row]) {
                var s = elements[row];
                var d = s
                    .replace(/年/g, "")
                    .replace(/月/g, "")
                    .replace(/日/g, "");
                date.push(Number(d));
            }
        }
        return date;
    };
    /**
     *  根据年月日数据源，计算出对应所在indexs
     * @param data: 日期二维数组 年月日
     * @param date: 当前日期
     * @returns number[]
     * */
    var getPickerValue = function (data, date) {
        var indexs = [];
        var dateS = [
            date.getFullYear() + "\u5E74",
            date.getMonth() + 1 + "\u6708",
            date.getDate() + "\u65E5"
        ];
        var _loop_1 = function (index) {
            var elements = data[index]; // 列数组
            var ds = dateS[index];
            var i = elements.findIndex(function (e) { return e === ds; });
            var ind = i <= -1 ? 0 : i;
            indexs.push(ind);
        };
        for (var index = 0; index < data.length; index++) {
            _loop_1(index);
        }
        return indexs;
    };
    /**
     * 当滚动选择，value 改变时触发 change 事件，event.detail = {value: value}；value为数组，表示 picker-view 内的 picker-view-column 当前选择的是第几项（下标从 0 开始）
     * @param e: CommonEventFunction<PickerViewProps.onChangeEventDetail>
     * @supported — weapp, swan, alipay, tt, rn
    */
    var onDateChange = function (e) {
        // 1. 拿到原始数组索引
        var indexs = e.detail.value;
        // 2. 判断滚动是哪一列
        var scrollIndex = columnChange(currentIndexsRef.current, indexs);
        var maxDayInd = pickerData[2].length;
        // 3. 根据索引拿到原始的年月日字符串
        var date = getChangeDate(pickerData, indexs);
        var pickerValueT = __spread(indexs);
        var dayInd = 0;
        if (scrollIndex == 0 || scrollIndex == 1) {
            maxDayInd = updateDays(date[0], date[1]);
            dayInd = maxDayInd - 1 < pickerValueT[2] ? maxDayInd : pickerValueT[2];
            pickerValueT = [pickerValueT[0], pickerValueT[1], dayInd];
        }
        // 4. 更正索引值
        setPickerValue(pickerValueT);
        // 5. 保存当前索引
        currentIndexsRef.current = indexs;
        // 6. 传真实日期
        date[2] = dayInd + 1;
        var realDate = date.join('/');
        var validDate = new Date(realDate);
        onChange && onChange(validDate);
    };
    /**
     * 更新天数组
     * @param y 年
     * @param m 月
     * @returns len number 天数组的长度
     */
    var updateDays = function (y, m) {
        var days = getDayRange(y, m);
        var arr = [pickerData[0], pickerData[1], days];
        setPickerData(arr);
        return days.length;
    };
    /**
     * 哪一列滚动
     * @param oldArr number[] 滚动前的状态
     * @param oldArr number[] 滚动前的状态
     *
     * @returns column
     */
    var columnChange = function (oldArr, newArr) {
        var column = -1;
        for (var i in oldArr) {
            var it = Number(i);
            if (oldArr[it] !== newArr[it]) {
                column = it;
            }
        }
        return column;
    };
    /**
     *  中间文案样式
     *  @param index number 行id
     *  @param col number 数据列
     *
     * @returns CSSProperties  样式集合
    */
    var getStyle = function (index, col) {
        var active = index === pickerValue[col];
        if (active && activeTextStyle) {
            return activeTextStyle;
        }
        return __assign({ overflow: "hidden", whiteSpace: "nowrap", textOverflow: "ellipsis", height: 34 + "px", lineHeight: 34 + "px", fontWeight: active ? 600 : 400, color: active ? "#FF7242" : "#000000" }, textStyle);
    };
    return (React.createElement(PickerView, { indicatorStyle: "height: 34px;", style: __assign({ height: 430 + 'rpx', backgroundColor: "#ffffff" }, style), value: pickerValue, onChange: onDateChange }, pickerData && pickerData.length > 0
        ? pickerData.map(function (d, index) {
            return (React.createElement(PickerViewColumn, { key: index, style: __assign({ textAlign: "center" }, columnStyle) }, d.map(function (item, i) {
                return (React.createElement(View, { style: getStyle(i, index), key: i }, item));
            })));
        })
        : null));
};
export default DatePicker;
